package de.gof.ppstool.kundenauftragsverwaltung.db;

import static REQUIRES_NEW;
import static de.gof.ppstool.kundenauftragsverwaltung.db.Kundenauftrag.FINDE_ALLE_KUNDENAUFTRAEGE;
import java.util.List;
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class KundenauftragsverwaltungDAO implements
		IKundenauftragsverwaltungDAO {
	@PersistenceContext
	private EntityManager em;

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public Kundenauftrag createKundenauftrag(Kundenauftrag kundenauftrag) {
		em.persist(kundenauftrag);
		return kundenauftrag;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public void deleteKundenauftrag(Kundenauftrag kundenauftrag) {
		if (kundenauftrag == null) {
			return;
		}

		if (!em.contains(kundenauftrag)) {
			kundenauftrag = em.find(Kundenauftrag.class,
					kundenauftrag.getKundenauftragId());
		}

		em.remove(kundenauftrag);
	}

	/**
	 * { @inheritDoc}
	 * @throws KundenauftragDeletedException  
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public Kundenauftrag editKundenauftrag(Kundenauftrag kundenauftrag)
			throws KundenauftragDeletedException {
		if (kundenauftrag == null) {
			return null;
		}

		kundenauftrag = em.merge(kundenauftrag);
		return kundenauftrag;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public Kundenauftrag findKundenauftrag(Long kundenauftrag_id)
			throws KundenauftragNotFoundException {
		if (kundenauftrag_id == null) {
			return null;
		}

		Kundenauftrag kundenauftrag = em.find(Kundenauftrag.class,
				kundenauftrag_id);
		if (kundenauftrag == null) {
			final KundenauftragNotFoundException excp = new KundenauftragNotFoundException(
					kundenauftrag_id);
			throw excp;
		}

		return kundenauftrag;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	@SuppressWarnings("unchecked")
	public List<Kundenauftrag> findeAlleKundenauftraege()
			throws KundenauftragNotFoundException {
		final Query query = em.createNamedQuery(FINDE_ALLE_KUNDENAUFTRAEGE);
		final List<Kundenauftrag> result = query.getResultList();
		return result;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public Prognose createPrognose(Prognose prognose) {
		em.persist(prognose);
		return prognose;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public void deletePrognose(Prognose prognose) {
		if (prognose == null) {
			return;
		}

		if (!em.contains(prognose)) {
			prognose = em.find(Prognose.class, prognose.getPrognose_id());
		}

		em.remove(prognose);
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public Prognose findPrognose(Long prognoseID)
			throws PrognoseNotFoundException {
		if (prognoseID == null) {
			return null;
		}

		Prognose prognose = em.find(Prognose.class, prognoseID);
		if (prognoseID == null) {
			final PrognoseNotFoundException excp = new PrognoseNotFoundException(
					prognoseID);
			throw excp;
		}

		return prognose;
	}

	/**
	 * { @inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	@Override
	@Transactional(propagation = REQUIRES_NEW)
	public List<Prognose> findAllPrognose() {
		final Query query = em.createNamedQuery(Prognose.FINDE_ALLE_PROGNOSEN);
		final List<Prognose> result = query.getResultList();
		return result;
	}

	/**
	 * { @inheritDoc}
	 * @throws KundenauftragDeletedException  
	 */
	@Transactional(propagation = REQUIRES_NEW)
	public Prognose editPrognose(Prognose prognose)
			throws PrognoseNotFoundException {
		if (prognose == null) {
			return null;
		}

		prognose = em.merge(prognose);
		return prognose;
	}

	@Override
	@Transactional(propagation = REQUIRES_NEW)
	public Prognose findePrognoseNachFahrradartUndPeriode(String fahrradart,
			String periode) throws PrognoseNotFoundException {
		Query query = em
				.createNamedQuery(Prognose.FINDE_PROGNOSE_NACH_FAHRRADART_UND_PERIODE);
		query.setParameter(Prognose.PARAM_FAHRRADART, fahrradart);
		query.setParameter(Prognose.PARAM_PERIODE, periode);
		Prognose p = null;
		try {
			p = (Prognose) query.getSingleResult();
		} catch (Exception e) {

			// wird unten abgefangen
		}

		if (p == null) {
			final PrognoseNotFoundException e = new PrognoseNotFoundException(
					fahrradart, periode);
			throw e;
		}

		return p;
	}

	@Override
	@Transactional(propagation = REQUIRES_NEW)
	public Kundenauftrag findeKundenauftragNachBemerkung(String bemerkung)
			throws KundenauftragNotFoundException {
		Query query = em
				.createNamedQuery(Kundenauftrag.FINDE_KUNDENAUFTRAG_NACH_BEMERKUNG);
		query.setParameter(Kundenauftrag.PARAM_BEMERKUNG, bemerkung);
		Kundenauftrag kundenauftrag = null;
		try {
			kundenauftrag = (Kundenauftrag) query.getSingleResult();
		} catch (Exception e) {

			// wird unten abgefangen
		}

		if (kundenauftrag == null) {
			final KundenauftragNotFoundException e = new KundenauftragNotFoundException(
					bemerkung);
			throw e;
		}

		return kundenauftrag;
	}

}
